package org.space.ai.service.impl;

import com.galaxy.common.core.constant.Constants;
import com.galaxy.common.core.domain.R;
import com.galaxy.common.redis.utils.RedisUtils;
import org.json.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.space.ai.service.MoonshotService;
import org.springframework.ai.util.json.schema.SpringAiSchemaModule;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.client.RestTemplate;


import lombok.RequiredArgsConstructor;
import org.space.ai.config.MoonshotConfig;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
//@CrossOrigin(origins = "http://127.0.0.1:8848")
public class MoonshotServiceImpl implements MoonshotService {
    private static final Logger log = LoggerFactory.getLogger(MoonshotServiceImpl.class);

    private final MoonshotConfig moonshotConfig;
    private final RestTemplate restTemplate;

    private final OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .build();

    @Override
    public String getMoonshotApiInfo() {
        String moonshotApiUrl = moonshotConfig.getPath();
        String moonshotResponse = restTemplate.getForObject(moonshotApiUrl, String.class);

        SpringAiSchemaModule springAiSchemaModule = new SpringAiSchemaModule();
        springAiSchemaModule.applyToConfigBuilder(new SchemaGeneratorConfigBuilder(new ObjectMapper()));

        return "Moonshot API Response: " + moonshotResponse;
    }

    public String getResponse(String userPrompt) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(moonshotConfig.getKey());

        Map<String, Object> message = Map.of("role", "user", "content", userPrompt);
        Map<String, Object> request = Map.of(
            "model", moonshotConfig.getType(),
            "messages", List.of(message)
        );

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(request, headers);
        ResponseEntity<Map> response = restTemplate.postForEntity(moonshotConfig.getPath() + "/v1/chat/completions", entity, Map.class);

        log.info("response: {}", response);

        List<Map<String, Object>> choices = (List<Map<String, Object>>) response.getBody().get("choices");
        Map<String, Object> messageData = (Map<String, Object>) choices.get(0).get("message");

        return (String) messageData.get("content");
    }

    /**
     * 获取图像描述
     *
     * @param imageFile 图像 URL
     * @return 图像描述
     */
    public String generateCaption(MultipartFile imageFile) {
        try {
            // 保存上传的图片到临时文件
            File tempFile = File.createTempFile("temp", ".jpg");
            try (FileOutputStream fos = new FileOutputStream(tempFile)) {
                fos.write(imageFile.getBytes());
            }

            // 读取图片并进行Base64编码
            byte[] imageBytes = Files.readAllBytes(tempFile.toPath());
            String imgBase64 = Base64.getEncoder().encodeToString(imageBytes);

            OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时时间
                .readTimeout(30, TimeUnit.SECONDS)     // 设置读取超时时间
                .writeTimeout(30, TimeUnit.SECONDS)    // 设置写入超时时间
                .build();

            // 构建请求体
            String json = String.format(
                "{\"model\":\"moonshot-v1-8k-vision-preview\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"image_url\",\"image_url\":{\"url\":\"data:image/jpeg;base64,%s\"}},{\"type\":\"text\",\"text\":\"请描述这个图片中自动售货机的问题，格式：[{errorType，errorContent},{errorType，errorContent},{errorType，errorContent}...]，如不是自动售货机，就输出null\"}]}]}",
                imgBase64
            );

            RequestBody body = RequestBody.create(json, okhttp3.MediaType.get("application/json; charset=utf-8"));
            Request request = new Request.Builder()
                .url(moonshotConfig.getPath() + "/v1/chat/completions")
                .post(body)
                .addHeader("Authorization", "Bearer " + moonshotConfig.getKey())
                .build();

            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
                JSONObject jsonObject = new JSONObject(response.body().string());
                String content = jsonObject.getJSONArray("choices").getJSONObject(0).getJSONObject("message").getString("content");
                System.out.println("描述："+content);
                return content;
            } catch (Exception e) {
                System.out.println(e);
            }
            return null;
        } catch (Exception e) {
            System.out.println(e);
        }
        return null;
    }
    /**
     * 验证反馈内容是否正确
     *
     * @param imageFile 图像 URL， 内容， 类型
     * @return 反馈内容是否正确
     */
    public R<String> feedbackContentVerification(MultipartFile imageFile, String content, String contentType,Long userId) {
        try {
            // 保存上传的图片到临时文件
            File tempFile = File.createTempFile("temp", ".jpg");
            try (FileOutputStream fos = new FileOutputStream(tempFile)) {
                fos.write(imageFile.getBytes());
            }

            // 读取图片并进行Base64编码
            byte[] imageBytes = Files.readAllBytes(tempFile.toPath());
            String imgBase64 = Base64.getEncoder().encodeToString(imageBytes);
            OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时时间
                .readTimeout(30, TimeUnit.SECONDS)     // 设置读取超时时间
                .writeTimeout(30, TimeUnit.SECONDS)    // 设置写入超时时间
                .build();

            // 构建请求体
            String json = String.format(
                "{\"model\":\"moonshot-v1-8k-vision-preview\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"image_url\",\"image_url\":{\"url\":\"data:image/jpeg;base64,%s\"}},{\"type\":\"text\",\"text\":\"请描述这个图片中的问题，是否是和这个反馈类容：'类型:"+contentType+"'，内容：'"+content+"'，相似，相似返回true,不相似返回false,其他的不要返回\"}]}]}",
                imgBase64
            );

            RequestBody body = RequestBody.create(json, okhttp3.MediaType.get("application/json; charset=utf-8"));
            Request request = new Request.Builder()
                .url(moonshotConfig.getPath() + "/v1/chat/completions")
                .post(body)
                .addHeader("Authorization", "Bearer " + moonshotConfig.getKey())
                .build();

            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
                JSONObject jsonObject = new JSONObject(response.body().string());
                String content1 = jsonObject.getJSONArray("choices").getJSONObject(0).getJSONObject("message").getString("content");
                System.out.println("结果："+content1);
                if(content1.equals("false") || content1.equals("False")){
                    Object feedback = RedisUtils.getCacheObject("feedback:"+userId);
                    int i = 0;
                    if(feedback != null){
                        i = Integer.parseInt(feedback.toString());
                    }

                    LocalDateTime now = LocalDateTime.now();

                    // 获取当前时间
                    LocalTime currentTime = now.toLocalTime();

                    // 计算今天已经过去多少分钟
                    long minutesPassed = currentTime.toSecondOfDay() / 60;
                    RedisUtils.setCacheObject("feedback:"+userId, i+1, Duration.ofMinutes(Constants.DAY-minutesPassed));
                    return R.ok("你提交的不符合","false");
                }
                RedisUtils.deleteObject("feedback:"+userId);
                return R.ok("符合信息",content1);
            } catch (Exception e) {
                System.out.println(e);
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        return R.ok("你提交的不符合","false");
    }


    @Override
    public R<String> feedbackContentVerification(String content, String contentType, Long userId) {
        try {
            OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时时间
                .readTimeout(30, TimeUnit.SECONDS)     // 设置读取超时时间
                .writeTimeout(30, TimeUnit.SECONDS)    // 设置写入超时时间
                .build();

            // 构建请求体
            String json = String.format(
                "{\"model\":\"moonshot-v1-8k-vision-preview\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"请判断以下内容是否为有效的反馈信息。反馈内容应描述售货机故障或系统出错，其他类型的反馈视为无效。" +
                    "'类型:"+contentType+"'，内容：'"+content+"'，是否是反馈问题，" +
                    "不能有违法或违规词汇，使用恶意谐音也不可以，正确反馈问题返回true,否则返回false,其他的不要返回\"}]}]}"

            );

            RequestBody body = RequestBody.create(json, okhttp3.MediaType.get("application/json; charset=utf-8"));
            Request request = new Request.Builder()
                .url(moonshotConfig.getPath() + "/v1/chat/completions")
                .post(body)
                .addHeader("Authorization", "Bearer " + moonshotConfig.getKey())
                .build();

            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
                JSONObject jsonObject = new JSONObject(response.body().string());
                String content1 = jsonObject.getJSONArray("choices").getJSONObject(0).getJSONObject("message").getString("content");
                System.out.println("结果："+content1);
                if(content1.equals("false") || content1.equals("False")){
                    Object feedback = RedisUtils.getCacheObject("feedback:"+userId);
                    int i = 0;
                    if(feedback != null){
                        i = Integer.parseInt(feedback.toString());
                    }
                    LocalDateTime now = LocalDateTime.now();

                    // 获取当前时间
                    LocalTime currentTime = now.toLocalTime();

                    // 计算今天已经过去多少分钟
                    long minutesPassed = currentTime.toSecondOfDay() / 60;
                    RedisUtils.setCacheObject("feedback:"+userId, i+1, Duration.ofMinutes(Constants.DAY-minutesPassed));
                    return R.ok("你提交的不符合","false");
                }
                RedisUtils.deleteObject("feedback:"+userId);
                return R.ok("符合信息",content1);
            } catch (Exception e) {
                System.out.println(e);
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        return R.ok("你提交的不符合","false");
    }
}
